package cc.shacocloud.mirage.restful.bind.annotation;

import cc.shacocloud.mirage.utils.annotation.AliasFor;

import java.lang.annotation.*;


/**
 * 请求映射,作用在方法上指定某个请求路径的处理方法映射
 * <p>
 * 使用 URL 模式映射方法，有三种选择：
 * <ul>
 *     <li>基于精确路径的路由 将映射模式设置为PATH，在这种情况下它只会匹配路径一致的请求，例如：/api/user</li>
 *     <li>基于路径前缀的路由 将映射模式设置为PATH，方式是在声明路径时使用一个 * 作为结尾，例如：/api/user/*</li>
 *     <li>基于正则表达式的路由 将映射模式设置为REGEX，即可使用正则表达式匹配路由的 URI 路径</li>
 * </ul>
 * 一些示例：
 * <ul>
 *     <li>/api/user- 匹配精确路径</li>
 *     <li>/api/user/*- 匹配指定前缀的路径</li>
 *     <li>"/api/user/:id"- 匹配精确路径并将其捕获为变量</li>
 *     <li>"\\/([^\\/]+)\\/([^\\/]+)"- 正则匹配路径并将其捕获为变量 例如：请求路径/api/user 路径匹配，api 可以通过参数 param0 获取，user 可以通过参数 param1 获取</li>
 *     <li>\\/(?<p0>[^\\/]+)\\/(?<p1>[^\\/]+)- 正则匹配路径并使用命名捕捉组的方式将其捕获为变量 例如：请求路径/api/user 路径匹配，api 可以通过参数 p0 获取，user 可以通过参数 p1 获取</li>
 * </ul>
 *
 * @author 思追(shaco)
 * @see GetMapping
 * @see PostMapping
 * @see PutMapping
 * @see PatchMapping
 * @see DeleteMapping
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
    
    /**
     * 路径的匹配模式，默认情况下为 {@link PathPatterns#PATH}
     * <p>
     * 在类级别声明无效
     */
    PathPatterns patterns() default PathPatterns.PATH;
    
    /**
     * 由该注解表达的主要的映射路径
     */
    @AliasFor("path")
    String[] value() default {};
    
    /**
     * 由该注解表达的主要的映射路径
     */
    @AliasFor("value")
    String[] path() default {};
    
    /**
     * 请求方式
     * <p>
     * 在类级别声明无效
     *
     * @see HttpMethod
     */
    HttpMethod[] method() default {};
    
    /**
     * 使用指定与匹配的请求 MIME 类型匹配的路由
     * <p>
     * 可以在精确的 MIME 类型匹配上进行匹配：
     * 如：text/html
     * <p>
     * 也支持子类型的通配符匹配：
     * 如：text/*
     */
    String[] consumes() default {};
    
    /**
     * 根据客户端可接受的MIME类型进行路由
     * <p>
     * HTTP accept标头用于表示客户端可以接受的响应的MIME类型。
     * 一个accept报头可具有由 "," 分隔的多个MIME类型
     * <p>
     * MIME类型还可以q附加一个值，该值表示如果有多个响应MIME类型可用于与accept标头匹配，则将应用加权。q值是介于0和1.0之间的数字。如果省略，则默认为1.0。
     * <p>
     * 例如，以下accept标头表示客户端将仅接受MIME类型text/plain：
     * text/plain
     * <p>
     * 通过以下方式，客户将接受text/plain或text/html：
     * text/plain, text/html
     * <p>
     * 通过以下操作，客户端将接受text/plain或text/html，text/html因为它具有更高的 q值（默认值为q = 1.0）：
     * text/plain; q=0.9, text/html
     */
    String[] produces() default {};
    
}
